import { isObject } from '@vue/shared'
import { isNaN, values } from 'lodash-es'
/**
 * @description 获取元素节点信息（在组件中的元素必须要传ctx）
 * @param  { String } selector 选择器 '.app' | '#app'
 * @param  { Boolean } all 是否多选
 * @param  { ctx } context 当前组件实例
 */
export const getRect = (selector : string, all = false, context ?: any) => {
	return new Promise((resolve, reject) => {
		let qurey = uni.createSelectorQuery()
		if (context) {
			qurey = uni.createSelectorQuery().in(context)
		}
		qurey[all ? 'selectAll' : 'select'](selector)
			.boundingClientRect(function (rect) {
				if (all && Array.isArray(rect) && rect.length) {
					return resolve(rect)
				}
				if (!all && rect) {
					return resolve(rect)
				}
				reject('找不到元素')
			})
			.exec()
	})
}

/**
 * @description 获取当前页面实例
 */
export function currentPage() {
	const pages = getCurrentPages()
	const currentPage = pages[pages.length - 1]
	return currentPage || {}
}

/**
 * @description 后台选择链接专用跳转
 */
interface Link {
	path : string
	name ?: string
	type : string
	isTab : boolean
	query ?: Record<string, any>
}

export enum LinkTypeEnum {
	'SHOP_PAGES' = 'shop',
	'CUSTOM_LINK' = 'custom'
}

export function jumpTo(link : string) {
	let linkArr = {}
	if (link.indexOf('http') == 0) {
		/*#ifdef H5*/
		window.open(link)
		/*#endif*/
		/*#ifdef APP-PLUS*/
		linkArr = {
			path: '/pages/webview/webview',
			query: {
				url: link
			}
		}
		/*#endif*/
		return
	} else {
		linkArr = { path: link }
	}
	navigateTo(linkArr)
}

export function navigateTo(link : Link, navigateType : 'navigateTo'|'switchTab' | 'reLaunch' = 'navigateTo') {
	const url = link.query ? `${link.path}?${objectToQuery(link.query)}` : link.path
	navigateType == 'navigateTo' && uni.navigateTo({ url })
	navigateType == 'reLaunch' && uni.reLaunch({ url })
	navigateType == 'switchTab' && uni.switchTab({ url })
}

/**
 * @description 是否为空
 * @param {unknown} value
 * @return {Boolean}
 */
export const isEmpty = (value : unknown) => {
	return value == null && typeof value == 'undefined'
}

/**
 * @description 对象格式化为Query语法
 * @param { Object } params
 * @return {string} Query语法
 */
export function objectToQuery(params : Record<string, any>) : string {
	let query = ''
	for (const props of Object.keys(params)) {
		const value = params[props]
		const part = encodeURIComponent(props) + '='
		if (!isEmpty(value)) {
			if (isObject(value)) {
				for (const key of Object.keys(value)) {
					if (!isEmpty(value[key])) {
						const params = props + '[' + key + ']'
						const subPart = encodeURIComponent(params) + '='
						query += subPart + encodeURIComponent(value[key]) + '&'
					}
				}
			} else {
				query += part + encodeURIComponent(value) + '&'
			}
		}
	}
	return query.slice(0, -1)
}

/**
 * @description 添加单位
 * @param {String | Number} value 值 100
 * @param {String} unit 单位 px em rem
 */
export const addUnit = (value : string | number, unit = 'rpx') => {
	return !Object.is(Number(value), NaN) ? `${value}${unit}` : value
}

/**
 * @description 格式化输出价格
 * @param  { string } price 价格
 * @param  { string } take 小数点操作
 * @param  { string } prec 小数位补
 */
export function formatPrice({ price, take = 'all', prec = undefined } : any) {
	let [integer, decimals = ''] = (price + '').split('.')

	// 小数位补
	if (prec !== undefined) {
		const LEN = decimals.length
		for (let i = prec - LEN; i > 0; --i) decimals += '0'
		decimals = decimals.substr(0, prec)
	}

	switch (take) {
		case 'int':
			return integer
		case 'dec':
			return decimals
		case 'all':
			return integer + '.' + decimals
	}
}

/**
 * @description 组合异步任务
 * @param  { string } task 异步任务
 */

export function series(...task : Array<(_arg : any) => any>) {
	return function () : Promise<any> {
		return new Promise((resolve, reject) => {
			const iteratorTask = task.values()
			const next = (res ?: any) => {
				const nextTask = iteratorTask.next()
				if (nextTask.done) {
					resolve(res)
				} else {
					Promise.resolve(nextTask.value(res)).then(next).catch(reject)
				}
			}
			next()
		})
	}
}

// /**
//  * @description 是否为纯字母
//  */
// export const precision = (val : string) => {
// 	console.log(val)
// 	let regex = /^[a-zA-Z]+$/;  // 正则表达式，匹配只有英文字母的情况
// 	if (regex.test(val)) {
// 		return val
// 	} else {
// 		return ""
// 	}
// }

/**
 * @description 格式化输出金额
 * @param  { string } money 金额
 * @param  { string } symbol 货币符号
 * @param  { string } rate 汇率
 * @param  { string } precision 精度
 * @return {string} Query语法
 */
export function formatMoney(money, symbol = '', rate = 1, precision = '') {
	if (precision == '') {
		precision = uni.getStorageSync('precision');
	}
	if (rate != 1) money = money * rate;

	money = (money / 1).toFixed(precision);
	if (symbol != '') {
		let regex = /^[a-zA-Z]+$/; // 正则表达式，匹配只有英文字母的情况
		if (regex.test(symbol)) {
			money = money + ' ' + symbol;
		} else {
			money = symbol + money;
		}
	}

	if (money == "NaN") money = "";

	return money
}

/**
 * @description 获取默认货币
 */
export function getCurrency() {
	return uni.getStorageSync('currency')?uni.getStorageSync('currency'):'';
}

/**
 * @description 获取默认货币
 */
export function getCurrency2() {
	return uni.getStorageSync('currency2')?uni.getStorageSync('currency2'):'';
}

/**
 * @description 时间戳转时间
 * @param  { number } timestamp 时间戳
 * @return {string} 
 */
export function formatDate(timestamp : number, format = "Y-m-d H:i:s") : string {
	var date = new Date(timestamp * 1000); // JavaScript中的时间戳单位为毫秒，需要乘以1000转换为秒
	var year = date.getFullYear();
	var month = (date.getMonth() + 1).toString().padStart(2, '0');
	var day = date.getDate().toString().padStart(2, '0');
	var hours = date.getHours().toString().padStart(2, '0');
	var minutes = date.getMinutes().toString().padStart(2, '0');
	var seconds = date.getSeconds().toString().padStart(2, '0');

	var dateStr = '';
	format = format.toLowerCase()
	for (var i = 0; i < format.length; i++) {
		switch (format[i]) {
			case 'y':
				dateStr += year;
				break
			case 'm':
				dateStr += month;
				break
			case 'd':
				dateStr += day;
				break
			case 'h':
				dateStr += hours;
				break
			case 'i':
				dateStr += minutes;
				break
			case 's':
				dateStr += seconds;
				break
			default:
				dateStr += format[i];
				break
		}
	}
	return dateStr;
}

/**
 * @description 获取语言
 */
export function t(key : string) {
	return uni.getStorageSync(key);
}

/**
 * @description 格式化字符串
 */
export function replaceStr(str, rule = "", val = "") {
	return str.replace(rule, val)
}
/**
 * @description 延时几秒执行
 */
export function randomDelay(min : number, max : number) : Promise<void> {
	return new Promise((resolve) => {
		const delay = Math.random() * (max - min) + min;
		setTimeout(() => {
			resolve();
		}, delay * 1000); // 转换为毫秒
	});
}